#!/usr/bin/env python
# encoding: utf-8

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import time,os
import xlwt
import xlrd
import xlsxwriter
from win32api import GetSystemMetrics

from ui.repeatMeasure import Ui_Dialog
from Help import Help
from Help import WATER_CMD
import binascii
help = Help()


class DataTabView(QTableView):
    def __init__(self, parent=None):
        '''表格初始化'''
        super(DataTabView, self).__init__(parent)
        self.model = QStandardItemModel(0, 0)
        #  self.HeaderList = ['x(mm)', 'y(mm)', 'z(mm)', '主测通道(mGy)', '监测通道(mGy)', '修正', '归一化']
        self.HeaderList = ['x(mm)', 'y(mm)', 'z(mm)', '主测通道(cGy/min)', '监测通道(cGy/min)']
        self.model.setHorizontalHeaderLabels(self.HeaderList)  #
        self.setModel(self.model)
        # 下面代码让表格100填满窗口
        self.horizontalHeader().setStretchLastSection(True)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.isClearChooseLine_Flag = False
        #  self.setMaximumHeight(250)

        self.clear_data()
        # 右键菜单设置
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.right_menu)

    def right_menu(self):
        self.menu = QMenu()
        exportAction = QAction("&导出excel", triggered=self.exportToExcel)
        self.menu.addAction(exportAction)
        self.menu.exec(QCursor.pos())

    def exportToExcel(self):
        f = QFileDialog.getSaveFileName(self, "导出Excel", '%s/data' % os.getcwd(), 'Excel Files(*.xls)')
        if f[0]:
            try:
                filename = f[0]
                wb = xlwt.Workbook()
                ws = wb.add_sheet('sheet1')  # sheetname
                data = []
                data.append(self.HeaderList)
                row = self.model.rowCount()
                for r in range(0, row):
                    x = self.model.data(self.model.index(r, 0))
                    y = self.model.data(self.model.index(r, 1))
                    z = self.model.data(self.model.index(r, 2))
                    t1 = self.model.data(self.model.index(r, 3))
                    t2 = self.model.data(self.model.index(r, 4))
                    if x and y and z and t1 and t2:
                        data = []
                        for r in range(0,row):
                            data.append([float(x), float(y), float(z), float(t1), float(t2)])
                        if data:
                            for i in range(0, len(data)):
                                for j in range(0, len(data[i])):
                                    ws.write(i, j, data[i][j])
                            wb.save(filename)
                            QMessageBox.warning(self, '提示', '导出成功!\r\n%s' % filename, QMessageBox.Yes)
                            return
                QMessageBox.warning(self, '警告', '导出失败!', QMessageBox.Yes)
            except:
                QMessageBox.warning(self, '警告', '无法导出!', QMessageBox.Yes)

    def clear_data(self):
        self.model.clear()
        self.model = QStandardItemModel(0, 0)
        self.model.setHorizontalHeaderLabels(self.HeaderList)  #
        self.setModel(self.model)

    def add_data(self, x='', y='', z='', t1='', t2=''):
        rowNum = self.model.rowCount()  # 总行数
        self.model.setItem(rowNum, 0, QStandardItem(str(x)))
        self.model.setItem(rowNum, 1, QStandardItem(str(y)))
        self.model.setItem(rowNum, 2, QStandardItem(str(z)))
        self.model.setItem(rowNum, 3, QStandardItem(str('%.2f'%t1)))
        self.model.setItem(rowNum, 4, QStandardItem(str('%.2f'%t2)))

    def insert_data(self, rowNum, x='', y='', z='', t1='', t2=''):
        # rowNum = self.model.rowCount()  # 总行数
        self.model.setItem(rowNum, 0, QStandardItem(str(x)))
        self.model.setItem(rowNum, 1, QStandardItem(str(y)))
        self.model.setItem(rowNum, 2, QStandardItem(str(z)))
        self.model.setItem(rowNum, 3, QStandardItem(str('%.2f'%t1)))
        self.model.setItem(rowNum, 4, QStandardItem(str('%.2f'%t2)))

    def get_standard(self, x, ave):
        import math
        n = len(x)
        s = 0
        for i in range(0, n):
            s = s + pow((int(x[i]) - ave), 2)
        s = math.sqrt(1 / (n - 1) * s)
        return s

    def get_data(self):
        rowNum = self.model.rowCount()  # 总行数
        x = [self.model.data(self.model.index(i, 1)) for i in range(0, rowNum)]
        line1 = [self.model.data(self.model.index(i, 4)) for i in range(0, rowNum)]
        line2 = [self.model.data(self.model.index(i, 5)) for i in range(0, rowNum)]
        return (x, line1, line2)

    def get_all_data(self):
        rowNum = self.model.rowCount()  # 总行数
        colNum = self.model.columnCount()  # 总行数
        data = []
        for j in range(0, colNum):
            col = [self.model.data(self.model.index(i, j)) for i in range(0, rowNum)]
            data.append(col)
        return data

class RepeatMeasureDialog(QDialog,Ui_Dialog):
    signal_msg = pyqtSignal(str,str)
    def __init__(self,parent=None, serial=None):
        super(QDialog, self).__init__(parent)
        self.setupUi(self)
        w = GetSystemMetrics (0)/1.2
        h = GetSystemMetrics (1)/1.2
        self.setFixedSize(w/1.2,h/1.2)
        # 串口模块
        self.serial = serial
        # self.tableView
        self.model = QStandardItemModel(0, 0)
        self.HeaderList = ['x(mm)','y(mm)','z(mm)','主测通道(cGy/min)','监测通道(cGy/min)']
        self.model.setHorizontalHeaderLabels(self.HeaderList)#
        self.tableView.setModel(self.model)
        #下面代码让表格100填满窗口
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 右键菜单设置
        self.tableView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tableView.customContextMenuRequested.connect(self.right_menu)

        self.pushButton_clearTable.clicked.connect(self.clearTable)
        self.pushButton_getResult.clicked.connect(self.getResult)

        # 开始测量和停止测量
        self.pushButton_startMeasure.clicked.connect(self.startMeasure)
        self.pushButton_stopMeasure.clicked.connect(self.stopMeasure)
        self.pushButton_setMeasureCycle.clicked.connect(self.setMeasureCycle)

        self.start_time = 0
        self.measure_flag = False
        self.signal_msg.connect(self.MessageBox)

    def right_menu(self):
        self.menu = QMenu()
        exportAction = QAction("&导出excel", triggered=self.exportToExcel)
        self.menu.addAction(exportAction)
        self.menu.exec(QCursor.pos())

    def exportToExcel(self):
        f = QFileDialog.getSaveFileName(self, "导出Excel", '%s/data' % os.getcwd(), 'Excel Files(*.xls)')
        if f[0]:
            try:
                filename = f[0]
                wb = xlwt.Workbook()
                ws = wb.add_sheet('sheet1')  # sheetname
                data = []
                data.append(self.HeaderList)
                row = self.model.rowCount()
                for r in range(0, row):
                    x = self.model.data(self.model.index(r, 0))
                    y = self.model.data(self.model.index(r, 1))
                    z = self.model.data(self.model.index(r, 2))
                    t1 = self.model.data(self.model.index(r, 3))
                    t2 = self.model.data(self.model.index(r, 4))
                    if x and y and z and t1 and t2:
                        data = []
                        for r in range(0,row):
                            data.append([float(x), float(y), float(z), float(t1), float(t2)])
                        if data:
                            for i in range(0, len(data)):
                                for j in range(0, len(data[i])):
                                    ws.write(i, j, data[i][j])
                            wb.save(filename)
                            QMessageBox.warning(self, '提示', '导出成功!\r\n%s' % filename, QMessageBox.Yes)
                            return
                QMessageBox.warning(self, '警告', '导出失败!', QMessageBox.Yes)
            except:
                QMessageBox.warning(self, '警告', '无法导出!', QMessageBox.Yes)

    def cmd_send(self, cmd_list):
        cmd = help.cmd_build(cmd_list)
        if self.serial.isOpen():
            data = binascii.unhexlify(cmd)
            print('发送命令：', ' '.join([cmd[i * 2:i * 2 + 2] for i in range(0, int(len(cmd) / 2))]))
            self.serial.write(data)
        else:
            QMessageBox.information(self, '通信提示', '通信异常,请检查通信接口', QMessageBox.Yes)

    def startMeasure(self):
        cmd = WATER_CMD['开始测量']
        self.cmd_send(cmd)
        self.measure_flag = True

    def stopMeasure(self):
        cmd = WATER_CMD['停止测量']
        self.cmd_send(cmd)
        self.measure_flag = False

    def setMeasureCycle(self):
        '''设置测量频率'''
        cycle = int(self.comboBox.currentText())
        print('设置传输速度:%sms' % cycle)
        cmd = WATER_CMD['设置传输速度']
        cmd[4] = hex(cycle).replace('0x', '').zfill(4).upper()
        self.cmd_send(cmd)

    def serial_deal(self, cmd, data, pos):
        """ 线程接收信息处理，提示消息需要用信号发送的方式"""
        if cmd == '71':
            if self.measure_flag:
                '''调试测量数据'''
                t1 = 0
                t2 = 0
                if data[:2] == 'FF':
                    t1 = int(data[:8], 16) - int('FFFFFFFF', 16) - 1
                else:
                    t1 = int(data[:8], 16)
                if data[-8:-6] == 'FF':
                    t2 = int(data[-8:], 16) - int('FFFFFFFF', 16) - 1
                else:
                    t2 = int(data[-8:], 16)
                x = pos[0]
                y = pos[1]
                z = pos[2]
                self.table_add_data(x=x,y=y,z=z, t1=t1, t2=t2)
        if cmd == '73':  # 停止测量
            pass
        if cmd == '41':  # 停止测量
            self.signal_msg.emit('提示', '设置传输速度成功')

    def table_add_data(self,x='',y='',z='',t1='',t2=''):
        rowNum = self.model.rowCount()  # 总行数
        # t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        # print(time.time())
        t = time.time()-self.start_time
        if t>100:
            t=0
        self.start_time =time.time()
        # self.model.setItem(rowNum, 0, QStandardItem(str('%dms'%(t*1000))))
        self.model.setItem(rowNum, 0, QStandardItem(str(x)))
        self.model.setItem(rowNum, 1, QStandardItem(str(y)))
        self.model.setItem(rowNum, 2, QStandardItem(str(z)))
        self.model.setItem(rowNum, 3, QStandardItem(str('%.2f'%t1)))
        self.model.setItem(rowNum, 4, QStandardItem(str('%.2f'%t2)))

    def clearTable(self):
        "清空表格"
        self.model.clear()
        self.model = QStandardItemModel(0, 0)
        self.model.setHorizontalHeaderLabels(self.HeaderList)#
        self.tableView.setModel(self.model)

    def getResult(self):
        "计算结果"
        try:
            row = self.model.rowCount()  # 总行数
            Tm = [float(self.model.data(self.model.index(i, 3))) for i in range(0,row)]
            Ts = [float(self.model.data(self.model.index(i, 4))) for i in range(0,row)]
            ave_Tm = sum(Tm)/len(Tm)
            ave_Ts = sum(Ts)/len(Ts)
            S_Tm = (sum([(m-ave_Tm)**2 for m in Tm])/(len(Tm)-1))**0.5
            S_Ts = (sum([(m-ave_Ts)**2 for m in Ts])/(len(Ts)-1))**0.5
            repeat_Tm = (S_Tm/ave_Tm)
            repeat_Ts = (S_Ts/ave_Ts)
            self.model.setItem(0, 5, QStandardItem("主测通道重复性:"))
            self.model.setItem(0, 6, QStandardItem('%.2f%%'%(repeat_Tm*100)))
            self.model.setItem(1, 5, QStandardItem("监测通道重复性:"))
            self.model.setItem(1, 6, QStandardItem('%.2f%%'%(repeat_Ts*100)))
        except:
            self.MessageBox('提示', '参数计算错误')

    def MessageBox(self,title='',msg=''):
        QMessageBox.information(self,title,msg,QMessageBox.Yes)

    def reject(self):
        # self.pushButton_stopMeasure.click()
        self.stopMeasure()
        QDialog.reject(self)



if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = RepeatMeasureDialog()
    win.show()
    app.exec_()

